package com.kate.mall.oauth.controller;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.kate.mall.oauth.constant.AuthConstants;
import com.kate.mall.oauth.constant.MessageConstant;
import com.kate.mall.oauth.domain.Oauth2TokenDto;
import com.kate.mall.common.utils.R;
import com.nimbusds.jose.JWSObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.security.Principal;
import java.text.ParseException;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 自定义Oauth2获取令牌接口
 * Created by kate2chan on 2020/7/17.
 */
@RestController
@RequestMapping("/oauth")
@Slf4j
public class AuthController {

    @Autowired
    private TokenEndpoint tokenEndpoint;
    /**
     * Oauth2登录认证
     */
    @RequestMapping(value = "/token", method = RequestMethod.POST)
    public R postAccessToken(Principal principal, @RequestParam Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
        OAuth2AccessToken oAuth2AccessToken = tokenEndpoint.postAccessToken(principal, parameters).getBody();
        Oauth2TokenDto oauth2TokenDto = Oauth2TokenDto.builder()
                .token(oAuth2AccessToken.getValue())
                .refreshToken(oAuth2AccessToken.getRefreshToken().getValue())
                .expiresIn(oAuth2AccessToken.getExpiresIn())
                .tokenHead("Bearer ").build();  //"Bearer xxx"

        return  R.ok().put("data",oauth2TokenDto);

    }

    @Resource
    private RedisTemplate redisTemplate;

    @DeleteMapping("/logout")
    public R logout(HttpServletRequest request) throws ParseException {
        String token = request.getHeader("Authorization");
        log.info("logout ，current token is :{}",token);

        token = token.replace("Bearer", Strings.EMPTY);
        JWSObject jwsObject = JWSObject.parse(token);
        String payload = jwsObject.getPayload().toString();


        JSONObject jsonObject = JSONUtil.parseObj(payload);
        String jti = jsonObject.getStr("jti"); // JWT唯一标识
        long exp = jsonObject.getLong("exp"); // JWT过期时间戳(单位:秒)

        long currentTimeSeconds = System.currentTimeMillis() / 1000;

        if (exp < currentTimeSeconds) { // token已过期
            return R.error(MessageConstant.CREDENTIALS_EXPIRED);
        }
        redisTemplate.opsForValue().set(AuthConstants.TOKEN_BLACKLIST_PREFIX + jti, null, (exp - currentTimeSeconds), TimeUnit.SECONDS);
        return R.ok("退出成功");
    }

    //public Object handleForWxAppAuth(@RequestBody WxLoginInfo wxLoginInfo, HttpServletRequest request) {
    //    String code = wxLoginInfo.getCode();
    //    UserInfo userInfo = wxLoginInfo.getUserInfo();
    //    if (code == null || userInfo == null) {
    //        return ResponseUtil.badArgument();
    //    }
    //
    //    String sessionKey = null;
    //    String openId = null;
    //    try {
    //        WxMaJscode2SessionResult result = this.wxService.getUserService().getSessionInfo(code);
    //        sessionKey = result.getSessionKey();
    //        openId = result.getOpenid();
    //    } catch (Exception e) {
    //        e.printStackTrace();
    //    }
    //
    //    if (sessionKey == null || openId == null) {
    //        return ResponseUtil.fail();
    //    }
    //
    //    LitemallUser user = userService.queryByOid(openId);
    //    if (user == null) {
    //        user = new LitemallUser();
    //        user.setUsername(openId);
    //        user.setPassword(openId);
    //        user.setWeixinOpenid(openId);
    //        user.setAvatar(userInfo.getAvatarUrl());
    //        user.setNickname(userInfo.getNickName());
    //        user.setGender(userInfo.getGender());
    //        user.setUserLevel((byte) 0);
    //        user.setStatus((byte) 0);
    //        user.setLastLoginTime(LocalDateTime.now());
    //        user.setLastLoginIp(IpUtil.getIpAddr(request));
    //        user.setSessionKey(sessionKey);
    //
    //        userService.add(user);
    //
    //        // 新用户发送注册优惠券
    //        couponAssignService.assignForRegister(user.getId());
    //    } else {
    //        user.setLastLoginTime(LocalDateTime.now());
    //        user.setLastLoginIp(IpUtil.getIpAddr(request));
    //        user.setSessionKey(sessionKey);
    //        if (userService.updateById(user) == 0) {
    //            return ResponseUtil.updatedDataFailed();
    //        }
    //    }
    //
    //    // token
    //    String token = UserTokenManager.generateToken(user.getId());
    //
    //    Map<Object, Object> result = new HashMap<Object, Object>();
    //    result.put("token", token);
    //    result.put("userInfo", userInfo);
    //    return ResponseUtil.ok(result);
    //}


    //private CommonResult handleForWxAppAuth(Principal principal, Map<String, String> parameters) throws WxErrorException, HttpRequestMethodNotSupportedException {
    //
    //    String code = parameters.get("code");
    //    if (StrUtil.isBlank(code)) {
    //        CommonResult.validateFailed("code参数错误");
    //    }
    //
    //    WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(code);
    //    String openid = session.getOpenid();
    //    String sessionKey = session.getSessionKey();
    //
    //    Result<MemberDTO> result = remoteUmsMemberService.loadMemberByOpenid(openid);
    //    if (!ResultCode.SUCCESS.getCode().equals(result.getCode())) {
    //        throw new BizException("获取会员信息失败");
    //    }
    //    MemberDTO memberDTO = result.getData();
    //    String username;
    //    if (memberDTO == null) { // 微信授权登录 会员信息不存在时 注册会员
    //        String encryptedData = parameters.get("encryptedData");
    //        String iv = parameters.get("iv");
    //
    //        WxMaUserInfo userInfo = wxService.getUserService().getUserInfo(sessionKey, encryptedData, iv);
    //        if (userInfo == null) {
    //            throw new BizException("获取用户信息失败");
    //        }
    //        UmsMember member = new UmsMember()
    //                .setNickname(userInfo.getNickName())
    //                .setAvatar(userInfo.getAvatarUrl())
    //                .setGender(Integer.valueOf(userInfo.getGender()))
    //                .setOpenid(openid)
    //                .setUsername(openid)
    //                .setPassword(passwordEncoder.encode(openid).replace(AuthConstants.BCRYPT, Strings.EMPTY)) // 加密密码移除前缀加密方式 {bcrypt}
    //                .setStatus(Constants.STATUS_NORMAL_VALUE);
    //
    //        Result res = remoteUmsMemberService.add(member);
    //        if (!ResultCode.SUCCESS.getCode().equals(res.getCode())) {
    //            throw new BizException("注册会员失败");
    //        }
    //        username = openid;
    //    } else {
    //        username = memberDTO.getUsername();
    //    }
    //
    //    // oauth2认证参数对应授权登录时注册会员的username、password信息，模拟通过oauth2的密码模式认证
    //    parameters.put("username", username);
    //    parameters.put("password", username);
    //
    //    OAuth2AccessToken oAuth2AccessToken = tokenEndpoint.postAccessToken(principal, parameters).getBody();
    //    Oauth2Token oauth2Token = Oauth2Token.builder()
    //            .token(oAuth2AccessToken.getValue())
    //            .refreshToken(oAuth2AccessToken.getRefreshToken().getValue())
    //            .expiresIn(oAuth2AccessToken.getExpiresIn())
    //            .build();
    //    return Result.success(oauth2Token);
    //
    //}
}
